import { useEffect, useMemo, useRef, useState } from 'react';
import { flushSync } from 'react-dom';
import MinDomRender from '../MinDomRender';
const VirtualList = ({ props }) => {
  const {
    width,
    height,
    style = {},
    className = '',
    itemCount,
    id = 'id',
    itemSize,
    overscan = 10,
    Item,
    loadMoreFn,
  } = props;

  const list = useMemo(() => Array.from(Array(itemCount).keys()), [itemCount]);
  const showCount = useMemo(() => Math.floor(height / itemSize), [height, itemSize]);

  const extra = useMemo(() => showCount * (overscan > 0 ? Math.ceil(overscan) : 10), [overscan, showCount]);

  const [start, setStart] = useState(0);
  const [end, setEnd] = useState(showCount);
  const [itemHeight, setItemHeight] = useState(new Array(itemCount - 1).fill(itemSize));

  const ref = useRef(null);
  const handleScroll = useRef(null);

  const setItemHeightFn = (index, height) => {
    flushSync(() => {
      setItemHeight((prev) => {
        const newArr = [...prev];
        newArr[index] = height;
        return newArr;
      });
    });
  };

  useEffect(() => {
    ref.current?.removeEventListener('scroll', (e) => handleScroll.current(e));
    handleScroll.current = (e) => {
      const currentStart = Math.floor(e.target.scrollTop / itemSize) + 1;
      flushSync(() => {
        if (currentStart + showCount / 2 > itemCount) return;
        setStart(currentStart);
        setEnd(currentStart + showCount);
      });
      if (e.target.scrollTop === 0) {
        loadMoreFn('last');
      }
    };
    ref.current.addEventListener('scroll', (e) => handleScroll.current(e));
    return ref.current?.removeEventListener('scroll', (e) => handleScroll.current(e));
  }, [showCount, itemCount]);

  useEffect(() => {
    flushSync(() => {
      setEnd(start + showCount);
    });
  }, [showCount]);

  useEffect(() => {
    if (end + showCount >= itemCount) {
      loadMoreFn('next');
    }
  }, [end, showCount]);

  useEffect(() => {
    // console.log(itemHeight, list.length);
  }, [itemHeight]);
  return (
    <div className={className} style={{ ...style, width, height, overflow: 'auto', position: 'relative' }} ref={ref}>
      <div style={{ height: itemHeight.reduce((sum, i) => sum + i, 0) }} key={start}>
        {list.map((item, index) => {
          if (index > 170) {
            console.log(index, start, start - extra, index < start - extra);
          }
          if (index < start - extra || index >= end + extra) {
            return null;
          }
          return <MinDomRender index={index} itemHeight={itemHeight} setItemHeight={setItemHeightFn} Item={Item} />;
          return Item({ index, style });
        })}
      </div>
    </div>
  );
};
export default VirtualList;
